(!) Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags.

Command Line Parsing with TCLAP

Description: Introduction to command line parsing with TCLAP.

Keywords: ecl command line parsing

Tutorial Level: BEGINNER

For a more detailed tutorial, visit the TCLAP documentation. Some common use cases are outlined below.

Initialisation

A single object is used to parse the command line. Initialise it with a few default properties. These will be used to automatically generate a --help argument.

   1 // Supply a program description, argument separator (optional) and version number (optional).
   2 CmdLine cmd("This is a test program to test the command line parsing facilities provided by TCLAP.");
   3 // CmdLine cmd("This is a test program to test the command line parsing facilities provided by TCLAP.", ' ', "0.01");
   4 

Adding Arguments

Valid argument types include:

  • ecl::SwitchArg : simple boolean.

  • ecl::ValueArg : expect some value on the command line.

  • ecl::MultiArg : permit multiple values for an argument which get stored in a vector.

  • ecl::MultiSwitchArg : as above, but for booleans

  • ecl::UnlabeledValueArg : does not use a flag (like the arguments for copy), order is important!

  • ecl::UnlabeledMultiArg : reads in all remaining unlabelled args (like rm file1.txt file2.txt etc.)

Toggles/Switches

   1 // Add a boolean (flag, name, description, default)
   2 SwitchArg debug("d","debug","Enable debugging.", false);
   3 cmd.add(debug);

You would call the above program (supposing it has name foo):

> foo -d false

Labelled

   1 // Add a boolean (flag, name, description, default)
   2 SwitchArg debug("d","debug","Enable debugging.", false);
   3 cmd.add(debug);
   4 
   5 // Add an integer 
   6 // (flag,name,description,compulsory flag,default value,type hint")
   7 ValueArg<int> intArg("t","test","An integer argument for testing.",false,5,"integer");
   8 
   9 cmd.add(intArg);

Custom ValueArg types can be used so long as they implement the >> operator.

> foo --test 3 

Unlabelled

These are unlabelled (like what you do with cp my_file_here my_file_there).

   1 // Not a regular option (name,description,compulsory flag,default value,type hint")
   2 UnlabeledValueArg<std::string> outputDirArg("output_dir","Output directory for rectified images.",true,"./rectified","string");
   3 cmd.add(outputDirArg);

> foo /home/snorri/images

Parsing the Arguments

   1 cmd.parse(argc,argv);
   2 bool debug = debugSwitch.getValue();
   3 int test = testArg.getValue();
   4 std::String output_dir = outputDirArg.getValue();

Allowing ROS to Pass

If you want to add your command line parsing program to a roslaunch, you'll need to let it know what it needs to parse and what it needs to pass... This can be achieved by the -- argument (literally means, 'ignore the rest'). An example:

   1     <node name="service_relay" pkg="foo" type="service_relay" args="-r 2 --">
   2         <remap from="service_relay/foo" to="/bar"/>
   3     </node>

Alternatively you can prune the ros args before they get to the command line parser in the code itself:

   1 #include <ros/init.h>
   2 
   3 // ....
   4 
   5 std::vector<std::string> myargs;
   6 ros::removeROSArgs(argc, argv, myargs);
   7 char** myargv = new char*[myargs.size()]; //array to emulate argv.
   8 for(int i = 0, ie = myargs.size(); i < ie; ++i)
   9 {
  10   myargv[i] = const_cast<char*>(myargs[i].data());
  11 }
  12 cmd.parse(myargs.size(), myargv);

Wiki: ecl_command_line/Tutorials/Command Line Parsing with TCLAP (last edited 2016-12-15 00:48:01 by DanielStonier)